package org.ceva.training.util.mail;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.velocity.app.VelocityEngine;
import org.ceva.training.util.constants.Constant;
import org.springframework.mail.MailSendException;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.mail.javamail.MimeMessagePreparator;
import org.springframework.ui.velocity.VelocityEngineUtils;

import javax.mail.Address;
import javax.mail.MessagingException;
import javax.mail.SendFailedException;
import javax.mail.internet.MimeMessage;


import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class SendMailImpl implements SendMail {
	private JavaMailSender mailSender;
	private static String bcc;
	private static String cc;
	private static String to;
	private static String mailTemplate;
	private static String from;
	private VelocityEngine velocityEngine;
	
	private String courseScheduledTemplate;
	private String forgotpasswordTemplate;
	private String invalidMailIdTemplate;
	
	private static String subject;
	private static Map model = new HashMap();

	
	private final Log logger = LogFactory.getLog(getClass());
	
	public SendMailImpl() {
		SendMailImpl.bcc=null;
		SendMailImpl.cc=null;
		SendMailImpl.subject= null;
	}

	public void setMailSender(JavaMailSender mailSender) {
		this.mailSender = mailSender;
	}
	
	public void setVelocityEngine(VelocityEngine velocityEngine) {
	      this.velocityEngine = velocityEngine;
	}
	
	public static String getFrom() {
		return from;
	}

	public void setFrom(String from) {	
		SendMailImpl.from = from;
		
	}

	public void sendMail() {
		 try{
			logger.info("Send Mail ");
			MimeMessagePreparator preparator = new MimeMessagePreparator() {
            public void prepare(MimeMessage mimeMessage) throws Exception {
               MimeMessageHelper message = new MimeMessageHelper(mimeMessage);
               //message.setValidateAddresses(false);               
               logger.info("To Mail : "+SendMailImpl.to);
              
               if(SendMailImpl.to.indexOf(",")>0)
               {
            	   String[] emailIds = SendMailImpl.to.split(",");
            	   for(int i=0;i<emailIds.length;i++)
            	   {
            		   logger.info("Emails Ids to : " + emailIds[i]);
            		   message.addTo(emailIds[i]);
            	   }
            	   
               }else{
            	   message.setTo(SendMailImpl.to);
               }
               
               if(SendMailImpl.bcc != null)
               {
            	   if(SendMailImpl.bcc != null && SendMailImpl.bcc.indexOf(",")>0)
            	   {
            		   String[] emailIds = SendMailImpl.bcc.split(",");
            		   for(int i=0;i<emailIds.length;i++)
            		   {
            			   logger.info("Emails Ids BCC: " + emailIds[i]);
            			   message.addBcc(emailIds[i]);
            		   }

            	   }else{
            		   message.setBcc(SendMailImpl.bcc);
            	   }
               }
               
               if(SendMailImpl.cc != null){
            	   if(SendMailImpl.cc != null && SendMailImpl.cc.indexOf(",")>0)
            	   {
            		   String[] emailIds = SendMailImpl.cc.split(",");
            		   for(int i=0;i<emailIds.length;i++)
            		   {
            			   logger.info("Emails Ids CC : " + emailIds[i]);
            			   message.addCc(emailIds[i]);
            		   }

            	   }else{
            		   message.setCc(SendMailImpl.to);
            	   }
               }
               
               
               if(SendMailImpl.subject != null )
                    message.setSubject(SendMailImpl.subject);
               
        
               message.setFrom(SendMailImpl.from); // could be parameterized...
               logger.info("To Mail : "+SendMailImpl.from);
               logger.info("Send Mail template : "+ SendMailImpl.mailTemplate);
               String text = VelocityEngineUtils.mergeTemplateIntoString(
               velocityEngine, SendMailImpl.mailTemplate, SendMailImpl.model);
               message.setText(text, true);               
            }
         };
        
		 mailSender.send(preparator);		
		}catch (Exception exp) {
			// TODO: handle exception
			Address[] validUnsent=null;
			Address[] invalid =null;
			StringBuffer bcc= new StringBuffer("");
			StringBuffer messagetext = new StringBuffer("There are Invalid Mailids in System.Please Correct them <br><br>");
			exp.printStackTrace();
			if(exp instanceof MailSendException) {
				MailSendException mex = (MailSendException) exp;				
				Map mapex = mex.getFailedMessages();
				Iterator exitr = mapex.keySet().iterator() ;
				while(exitr.hasNext())
				{				 
					Exception ex = (Exception) mapex.get(exitr.next());	
					  do {
						 if (ex instanceof SendFailedException) {
							 System.out.println("Exception Is of Type SendFailedException");
					          SendFailedException sfex = (SendFailedException) ex;
					          invalid = sfex.getInvalidAddresses();
					          if (invalid != null) {
					            System.out.println("    ** Invalid Addresses");		          
					              for (int i = 0; i < invalid.length; i++)
					              {
					                System.out.println("         " + invalid[i]);
					                messagetext.append(invalid[i]+"<br>");
					              }
					          }
					          validUnsent = sfex.getValidUnsentAddresses();
					          if (validUnsent != null) {
					            System.out.println("    ** ValidUnsent Addresses");		           
					              for (int i = 0; i < validUnsent.length; i++)
					              {
					                System.out.println("         " + validUnsent[i]);
					                bcc.append(validUnsent[i]+",");				                
					              }
					          }
					          Address[] validSent = sfex.getValidSentAddresses();
					          if (validSent != null) {
					            System.out.println("    ** ValidSent Addresses");		            
					              for (int i = 0; i < validSent.length; i++)					              
					                System.out.println("         " + validSent[i]);		            
					          }				      
						 }		
							if (validUnsent != null) {
								System.out.println("Sending Mail Again .........");
							      this.setTo(this.getFrom());
								  bcc.replace(bcc.length()-1, bcc.length(), "");  
								  this.setBCC(bcc.toString());
								  this.setCC(null);
								  this.sendMail();
							}	
							if (invalid != null) {								
							      this.setTo(this.getFrom());
							     this.setBCC(null);
							      this.setCC(null);
							      this.mailTemplate = this.getInvalidMailIdTemplate();
							      HashMap HashMail = new HashMap();									      
							      HashMail.put("MESSAGETEXT", messagetext.toString());
							      this.setEmailData(HashMail);
							      this.setSubject("Invalid MailIds In System ");								
							}	
					 System.out.println();	
				 	 if (ex instanceof MessagingException)
				          ex = ((MessagingException) ex).getNextException();
				        else
				          ex = null;
				      } while (ex != null);
				    
				}    //End of while 		        
			} // End of if
		
		}
		
	}

	public void setBCC(String bcc) {
		SendMailImpl.bcc = bcc;
	}

	public void setCC(String cc) {
		SendMailImpl.cc = cc;
	}
	public void setEmailData(Map model)
	{
		SendMailImpl.model = model;
	}
	public void setMailTemplate(String mailTemplate) {
		SendMailImpl.mailTemplate = mailTemplate;
	}

	public void setTo(String toMailIds) {
		SendMailImpl.to=toMailIds;
	}

	
	public void mailType(long type) {
		if(type==Constant.TRAININGSCHEDULE)
		{
			SendMailImpl.mailTemplate = this.getCourseScheduledTemplate();
		}
		if(type==Constant.FORTGOTPASSWORD)
		{
			SendMailImpl.mailTemplate = this.getForgotpasswordTemplate();
		}
		if(type==Constant.INVALIDMAILID)
		{
			SendMailImpl.mailTemplate = this.getInvalidMailIdTemplate();
		}			
	}

	public static String getSubject() {
		return SendMailImpl.subject;
	}

	public void setSubject(String subject) {
		SendMailImpl.subject = subject;
	}
	
	public String getInvalidMailIdTemplate() {
		return invalidMailIdTemplate;
	}

	public void setInvalidMailIdTemplate(String invalidMailIdTemplate) {
		this.invalidMailIdTemplate = invalidMailIdTemplate;
	}

	public String getCourseScheduledTemplate() {
		return courseScheduledTemplate;
	}

	public void setCourseScheduledTemplate(
			String courseScheduledTemplate) {
		this.courseScheduledTemplate = courseScheduledTemplate;
	}

	public String getForgotpasswordTemplate() {
		return forgotpasswordTemplate;
	}

	public void setForgotpasswordTemplate(String forgotpasswordTemplate) {
		this.forgotpasswordTemplate = forgotpasswordTemplate;
	}

	
}
